{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['love', 'my', 'dalmation'] classified as:  0\n",
      "['stupid', 'garbage'] classified as:  1\n"
     ]
    }
   ],
   "source": [
    "#!/usr/bin/python\n",
    "# coding=utf-8\n",
    "from numpy import *\n",
    "\n",
    "# 过滤网站的恶意留言  侮辱性：1     非侮辱性：0\n",
    "# 创建一个实验样本\n",
    "def loadDataSet():\n",
    "    postingList = [['my','dog','has','flea','problems','help','please'],\n",
    "                   ['maybe','not','take','him','to','dog','park','stupid'],\n",
    "                   ['my','dalmation','is','so','cute','I','love','him'],\n",
    "                   ['stop','posting','stupid','worthless','garbage'],\n",
    "                   ['mr','licks','ate','my','steak','how','to','stop','him'],\n",
    "                   ['quit','buying','worthless','dog','food','stupid']]\n",
    "    classVec = [0,1,0,1,0,1]\n",
    "    return postingList, classVec\n",
    "\n",
    "# 创建一个包含在所有文档中出现的不重复词的列表\n",
    "def createVocabList(dataSet):\n",
    "    vocabSet = set([])      # 创建一个空集\n",
    "    for document in dataSet:\n",
    "        vocabSet = vocabSet | set(document)   # 创建两个集合的并集\n",
    "    return list(vocabSet)\n",
    "\n",
    "# 将文档词条转换成词向量\n",
    "def setOfWords2Vec(vocabList, inputSet):\n",
    "    returnVec = [0]*len(vocabList)        # 创建一个其中所含元素都为0的向量\n",
    "    for word in inputSet:\n",
    "        if word in vocabList:\n",
    "            # returnVec[vocabList.index(word)] = 1     # index函数在字符串里找到字符第一次出现的位置  词集模型\n",
    "            returnVec[vocabList.index(word)] += 1      # 文档的词袋模型    每个单词可以出现多次\n",
    "        else: \n",
    "            print(\"the word: {}s is not in my Vocabulary!\").format(word)\n",
    "    return returnVec\n",
    "\n",
    "# 朴素贝叶斯分类器训练函数   从词向量计算概率\n",
    "def trainNB0(trainMatrix, trainCategory):\n",
    "    numTrainDocs = len(trainMatrix)\n",
    "    numWords = len(trainMatrix[0])\n",
    "    pAbusive = sum(trainCategory)/float(numTrainDocs)\n",
    "    # p0Num = zeros(numWords); p1Num = zeros(numWords)\n",
    "    # p0Denom = 0.0; p1Denom = 0.0\n",
    "    p0Num = ones(numWords);   # 避免一个概率值为0,最后的乘积也为0\n",
    "    p1Num = ones(numWords);   # 用来统计两类数据中，各词的词频\n",
    "    p0Denom = 2.0;  # 用于统计0类中的总数\n",
    "    p1Denom = 2.0  # 用于统计1类中的总数\n",
    "    for i in range(numTrainDocs):\n",
    "        if trainCategory[i] == 1:\n",
    "            p1Num += trainMatrix[i]\n",
    "            p1Denom += sum(trainMatrix[i])\n",
    "        else:\n",
    "            p0Num += trainMatrix[i]\n",
    "            p0Denom += sum(trainMatrix[i])\n",
    "            # p1Vect = p1Num / p1Denom\n",
    "            # p0Vect = p0Num / p0Denom\n",
    "    p1Vect = log(p1Num / p1Denom)    # 在类1中，每个次的发生概率\n",
    "    p0Vect = log(p0Num / p0Denom)      # 避免下溢出或者浮点数舍入导致的错误   下溢出是由太多很小的数相乘得到的\n",
    "    return p0Vect, p1Vect, pAbusive\n",
    "\n",
    "# 朴素贝叶斯分类器\n",
    "def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):\n",
    "    p1 = sum(vec2Classify*p1Vec) + log(pClass1)\n",
    "    p0 = sum(vec2Classify*p0Vec) + log(1.0-pClass1)\n",
    "    if p1 > p0:\n",
    "        return 1\n",
    "    else:\n",
    "        return 0\n",
    "\n",
    "def testingNB():\n",
    "    listOPosts, listClasses = loadDataSet()\n",
    "    myVocabList = createVocabList(listOPosts)\n",
    "    trainMat = []\n",
    "    for postinDoc in listOPosts:\n",
    "        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))\n",
    "    p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))\n",
    "    testEntry = ['love','my','dalmation']\n",
    "    thisDoc = array(setOfWords2Vec(myVocabList, testEntry))\n",
    "    print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))\n",
    "    testEntry = ['stupid','garbage']\n",
    "    thisDoc = array(setOfWords2Vec(myVocabList, testEntry))\n",
    "    print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))\n",
    "\n",
    "# 调用测试方法----------------------------------------------------------------------\n",
    "testingNB()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
